import * as glob from 'glob'
import * as Koa from 'koa'
import * as Router from 'koa-router'
import {join} from 'path'

type HTTPMETHOD = 'get' | 'put' | 'del' | 'post' | 'patch';
type LoadOption = {
    extname?: string;
}
type RouteOption = {
    // 前缀
    prefix?:string;
    middlewares?: Array<Koa.Middleware>;
}

const route = new Router();
// 装饰器执行顺序 先执行方法装饰器在执行类装饰器所以使用process.nextTick改变顺序
const decort  = (method:string,path:string,options:RouteOption = {}) => {
    // 方法装饰器
    return (target, property, descriptor) => {
        // target 目标类
        // property 类属性
        // descriptor 描述属性类
        process.nextTick(() => {
            let middlewares = [];
            middlewares = target.middlewares ? [...target.middlewares] : [];
            middlewares = options.middlewares ? [...middlewares,...options.middlewares,target[property]] : [...middlewares,target[property]];
            let url = options && options.prefix ? options.prefix + path : path;
            route[method](url, ...middlewares)
        })
    }
}

const method = (method:HTTPMETHOD) => (path:string, options?:RouteOption) => decort(method,path,options)

export const post = method('post');

export const get = method('get');

export const middlewares = (middlewares:Array<Koa.Middleware>) => { 
    return (target) => {
        // 中间件挂载到类原型上
        // target 是构造函数 类
        target.prototype.middlewares = middlewares;
    }
}

export default (floder:string = 'routes', options: LoadOption = {}) => {
    let extname = options.extname || `.{ts,js}`;
    // 查找这个路径下所有后缀为ts或js的文件
    glob.sync(join(floder,`./**/*${extname}`)).forEach(path => {
        // 加载文件
        require(path);
    })
    return route;
}
